package com.wolfcode.appointment.service.impl;

import java.util.List;

import com.wolfcode.appointment.domain.BusAppointment;
import com.wolfcode.appointment.domain.vo.BusStatementVo;
import com.wolfcode.appointment.enums.BusAppointmentEnum;
import com.wolfcode.appointment.enums.StatementEnum;
import com.wolfcode.appointment.mapper.BusAppointmentMapper;
import com.wolfcode.appointment.service.IBusAppointmentService;
import com.wolfcode.common.core.domain.model.LoginUser;
import com.wolfcode.common.utils.DateUtils;
import com.wolfcode.common.utils.LicensePlateUtil;
import com.wolfcode.common.utils.PhoneUtil;
import com.wolfcode.common.utils.SecurityUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.wolfcode.appointment.mapper.BusStatementMapper;
import com.wolfcode.appointment.domain.BusStatement;
import com.wolfcode.appointment.service.IBusStatementService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

/**
 * 结算单Service业务层处理
 * 
 * @author wolfcode
 * @date 2022-11-23
 */
@Service
public class BusStatementServiceImpl implements IBusStatementService 
{
    @Autowired
    private BusStatementMapper busStatementMapper;
    @Autowired
    private IBusAppointmentService appointmentService;
    @Autowired
    private BusAppointmentMapper appointmentMapper;
    /**
     * 查询结算单
     * 
     * @param id 结算单主键
     * @return 结算单
     */
    @Override
    public BusStatement selectBusStatementById(Long id)
    {
        return busStatementMapper.selectBusStatementById(id);
    }

    /**
     * 查询结算单列表
     * 
     * @param busStatement 结算单
     * @return 结算单
     */
    @Override
    public List<BusStatement> selectBusStatementList(BusStatement busStatement)
    {
        return busStatementMapper.selectBusStatementList(busStatement);
    }

    /**
     * 新增结算单
     * 
     * @param
     * @return 结果
     */
    @Override
    public int insertBusStatement(BusStatementVo busStatementVo)
    {
        // 1 非法参数校验
        Assert.notNull(busStatementVo,"非法参数");
        // 2 手机号码
        Assert.state(PhoneUtil.isMobileNumber(busStatementVo.getCustomerPhone())
                ,"手机格式不正确");
        // 3 车牌号码
        Assert.state(LicensePlateUtil.validate(busStatementVo.getLicensePlate())
                ,"车牌号码格式不正确");
        BusStatement busStatement=new BusStatement();
        BeanUtils.copyProperties(busStatementVo,busStatement);
        busStatement.setCreateTime(DateUtils.getNowDate());
        return busStatementMapper.insertBusStatement(busStatement);
    }

    /**
     * 修改结算单
     * 
     * @param
     * @return 结果
     */
    @Override
    public int updateBusStatement(BusStatementVo busStatementVo)
    {
        // 1 非法参数校验
        Assert.notNull(busStatementVo,"非法参数");
        // 2 手机号码
        Assert.state(PhoneUtil.isMobileNumber(busStatementVo.getCustomerPhone())
                ,"手机格式不正确");
        // 3 车牌号码
        Assert.state(LicensePlateUtil.validate(busStatementVo.getLicensePlate())
                ,"车牌号码格式不正确");
        BusStatement busStatement=new BusStatement();
        BeanUtils.copyProperties(busStatementVo,busStatement);
        return busStatementMapper.updateBusStatement(busStatement);
    }

    /**
     * 批量删除结算单
     * 
     * @param ids 需要删除的结算单主键
     * @return 结果
     */
    @Override
    public int deleteBusStatementByIds(Long[] ids)
    {
        return busStatementMapper.deleteBusStatementByIds(ids);
    }

    /**
     * 删除结算单信息
     * 
     * @param id 结算单主键
     * @return 结果
     */
    @Override
    public int deleteBusStatementById(Long id)
    {
        return busStatementMapper.deleteBusStatementById(id);
    }

    /**
     * 逻辑删除
     * @param id
     * @return
     */
    @Override
    public int removeById(Long id) {
        Assert.notNull(id,"非法参数");
        // 消费中，不可以删除
        BusStatement statement = busStatementMapper.selectBusStatementById(id);
        Assert.state(!(statement.getStatus()== StatementEnum.COSTING.ordinal())
                ,"消费中，不可以删除");
        BusStatement busStatement=new BusStatement();
        busStatement.setId(id);
        // 1 代表逻辑删除
        busStatement.setIsDelete(1);
        return busStatementMapper.updateBusStatement(busStatement);
    }

    /**
     * 生成结算单
     * @param id 预约客户id
     * @return
     */
    @Override
    @Transactional
    public BusStatement generateStatement(Long id) {
        // 校验
        Assert.notNull(id,"非法参数");
        //根据预约id查询客户的预约信息
        BusAppointment appointment = appointmentService.selectBusAppointmentById(id);
        Assert.notNull(appointment,"预约信息不存在");
        //已到店：才可以生成结算单
        //已结算，已支付
        Assert.state(appointment.getStatus()== BusAppointmentEnum.ARRIVAL.ordinal()
                              || appointment.getStatus()==BusAppointmentEnum.STATEMENT.ordinal()
                              || appointment.getStatus()==BusAppointmentEnum.PAYED.ordinal()
                ,"该状态不能生成结算单");
        // 通过预约id，查询结算单
        // 假如结算单存在，直接返回
        // 结算单假如不存在，才要生成
        BusStatement busStatement = busStatementMapper.selectBusStatementByAppointmentId(id);
        if(busStatement!=null){
            // 不合理
            //我期望它不是(结算单已支付，预约单已到店)
            Assert.state(!(busStatement.getStatus()==StatementEnum.PAYED.ordinal()
                            && appointment.getStatus()==BusAppointmentEnum.ARRIVAL.ordinal()),
                    "预约状态和结算单支付状态不一致");
            //我期望它不是(结算单已支付，预约单已结算)
            Assert.state(!(busStatement.getStatus()==StatementEnum.PAYED.ordinal()
                            && appointment.getStatus()==BusAppointmentEnum.STATEMENT.ordinal()),
                    "预约状态和结算单支付状态不一致");
//            busStatement.getStatus()==StatementEnum.PAYED.ordinal();
//            && appointment.getStatus()==BusAppointmentEnum.STATEMENT.ordinal();
            // 合理:合理方案不采纳
            // 检查状态
            // 已结算&&消费中
//            Assert.state(busStatement.getStatus()==StatementEnum.PAYED.ordinal()
//                    && appointment.getStatus()==BusAppointmentEnum.PAYED.ordinal(),
//                    "预约状态和结算单支付状态不一致");
            return busStatement;
        }

        //落库
        // 结算单表
        BusStatement statement=new BusStatement();
        BeanUtils.copyProperties(appointment,statement);
        statement.setId(null);
        statement.setStatus(StatementEnum.COSTING.ordinal());
        statement.setAppointmentId(id);
        busStatementMapper.insertBusStatement(statement);

        // 更改预约表信息
        BusAppointment updateAppointment=new BusAppointment();
        updateAppointment.setId(id);
        updateAppointment.setStatus(BusAppointmentEnum.STATEMENT.ordinal());
        appointmentMapper.updateBusAppointment(updateAppointment);
        return statement;
    }

    /**
     * 结算单id
     * @param id
     */

    @Override
    @Transactional
    public void pay(Long id) {
        //
        Assert.notNull(id,"非法参数");
        // 查询结算单
        // 消费中状态才可以支付
        BusStatement busStatement = busStatementMapper.selectBusStatementById(id);
        Assert.state(busStatement.getStatus() ==
                StatementEnum.COSTING.ordinal(),"消费中状态才可以支付");

        // 修改结算单消费状态
        // 支付时间，收款人
        LoginUser loginUser = SecurityUtils.getLoginUser();
        // 已支付
        BusStatement updateStatement=new BusStatement();
        updateStatement.setId(id);
        updateStatement.setStatus(StatementEnum.PAYED.ordinal());
        // 支付时间
        updateStatement.setPayTime(DateUtils.getNowDate());
        // 收款人
        updateStatement.setPayeeId(loginUser.getUserId());
        busStatementMapper.updateBusStatement(updateStatement);
        //预约客户
        Long appointmentId = busStatement.getAppointmentId();
        if(appointmentId!=null){
            // 结算单 --- 预约类型，非预约类型---有没有预约id
            // 修改预约状态
            // 已支付
            BusAppointment updateAppointment=new BusAppointment();
            updateAppointment.setId(appointmentId);
            updateAppointment.setStatus(BusAppointmentEnum.PAYED.ordinal());
            appointmentMapper.updateBusAppointment(updateAppointment);
        }

    }
}
